/*!
Copyright (C) 2014, 申瑞珉 (Ruimin Shen)

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <cassert>
#include <vector>
#include <utility>
#include <limits>
#include <cmath>

namespace otl
{
namespace indicator
{
namespace ms
{
template <typename _TReal, typename _TIterator>
std::vector<std::pair<_TReal, _TReal> > CalcSpaceBoundary(_TIterator begin, _TIterator end)
{
	std::vector<std::pair<_TReal, _TReal> > spaceBoundary((**begin).size());
	for (size_t i = 0; i < spaceBoundary.size(); ++i)
	{
		spaceBoundary[i].first = std::numeric_limits<_TReal>::max();
		spaceBoundary[i].second = std::numeric_limits<_TReal>::min();
	}
	for (_TIterator i = begin; i != end; ++i)
	{
		for (size_t j = 0; j < spaceBoundary.size(); ++j)
		{
			auto &point = (**i);
			assert(point.size() == spaceBoundary.size());
			if (point[j] < spaceBoundary[j].first)
				spaceBoundary[j].first = point[j];
			if (point[j] > spaceBoundary[j].second)
				spaceBoundary[j].second = point[j];
			assert(spaceBoundary[j].first <= spaceBoundary[j].second);
		}
	}
	return spaceBoundary;
}

template <typename _TReal>
_TReal CalcMaximumSpread(const std::vector<std::pair<_TReal, _TReal> > &spaceBoundary)
{
	_TReal sum = 0;
	for (size_t i = 0; i < spaceBoundary.size(); ++i)
	{
		const _TReal temp = spaceBoundary[i].second - spaceBoundary[i].first;
		sum += temp * temp;
	}
	return sqrt(sum);
}
}
}
}
